
declare global {
    interface String {
        /**根据指定格式解析数值 */
        dealValue(format: string): string;
    }
    interface Number {
        /**根据指定格式解析数值 */
        dealValue(format: string): string;
    }
}

export class StringFormat {
    /**
     * 压缩当前大数字
     * @param lang 语言
     * @param fixed 预留位数
     * @returns 
     */
    static converThousand(lang: 'zh' | 'k' = 'k', fixed: number = 2) {
        let value = this as unknown as number;
        let units: [string[], number[]] = {
            'zh': [
                [``, `万`, `亿`, `兆`, `京`],
                [bigNum('10000'), bigNum('100000000'), bigNum('1000000000000'), bigNum('10000000000000000')]
            ],
            'k': [
                ['', 'K', 'M', 'G', `T`],
                [bigNum('1000'), bigNum('1000000'), bigNum('1000000000'), bigNum('1000000000000')]
            ],
        }[lang] as any;
        let compressUnit = (v: number, count: number[], unit: string[], fixNum: number = 2) => {
            let res = v.toFixed(0);
            let index = 0;
            for (; index < count.length; index++) {
                if (v < count[index]) {
                    res = (v / count[index - 1]).toFixed(fixNum);
                    break;
                }
            }
            return res + unit[index];
        }
        switch (lang) {
            case `zh`:
                return compressUnit(value, units[1], units[0], fixed);
            case `k`:
                return compressUnit(value, units[1], units[0], fixed);
            default:
                break;
        }
    }

    /** yyyy-MM-dd hh:mm:ss S */
    static format(date: Date, fmt: string) {
        let o: any = {
            "M+": date.getMonth() + 1,                   // 月份 
            "d+": date.getDate(),                        // 日 
            "h+": date.getHours(),                       // 小时 
            "m+": date.getMinutes(),                     // 分 
            "s+": date.getSeconds(),                     // 秒 
            "q+": Math.floor((date.getMonth() + 3) / 3), // 季度 
            "S": date.getMilliseconds()                  // 毫秒 
        };
        if (/(y+)/.test(fmt)) {
            fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
        }
        for (let k in o) {
            if (new RegExp("(" + k + ")").test(fmt)) {
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
            }
        }
        return fmt;
    }

    /**
    * 根据指定格式解析数值
    * @param value 值
    * @param format 格式
    * @returns 数值
    * @example
    *  组件实际使用 后面跟数字表示限制参数
    *  {{0:sep}}将数字按分号显示   100000-> 100,000 
    *  {{0:per2}} 将取值0~1 变成 1~100,可以指定修饰的小数位数  
    *  {{0:int}} 将取值变成整数 
    *  {{0:fix2}}数值转换为小数
    *  {{0:limit3}}字符串长度限制 
    *  使用{{1:int}} 表示替换组件绑定的路径中第一个的数据模型 并限制为int整数
    */
    static dealValue(format: string): string {
        let value = this as any as number | string;
        if (format === ``) return value as string;
        format = format.toLowerCase().trim();//不区分大小
        let match_func = format.match(/^[a-z|A-Z]+/gi);//匹配到 format 中的 函数名
        let match_num = format.match(/\d+$/gi);   //匹配到 format 中的参数
        let func = match_func ? match_func[0] : ``;
        let num = match_num ? parseInt(match_num[0]) : 0;
        let res: number | string = ``;

        if (typeof value == `number`) {
            switch (func) {
                /** [value:int] 将取值变成整数 */
                case `int`: res = Math.round(value); break;
                /** [value:fix]数值转换为小数*/
                case `fix`: res = value.toFixed(num); break;
                /** [value:kmbt]将数字缩短显示为KMBT单位  */
                case `kmbt`: res = this.converThousand('k', 2); break;
                /** [value:per] 将取值0~1 变成 1~100,可以指定修饰的小数位数 */
                case `per`: res = Math.round(value * 100).toFixed(num); break;
                /**[value:sep]将数字按分号显示 100000-> 100,000 */
                case `sep`: res = Math.round(value).toString().replace(new RegExp(`(\\d)(?=(\\d{ 3}) + $)`, `ig`), "$1,"); break;
                default: break;
            }
        } else {
            switch (func) {
                /** [value:limit]字符串长度限制 */
                case `limit`: res = value.substring(0, num); break;
                default: break;
            }
            // res = value;
        }
        return res as string;
    }
}
